package $3exceptionhandler;

import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class FnCommonsLogging {

    public static void main(String[] args) {
        /**
         * 使用Commons Logging
         * Commons Logging是一个第三方日志库，它是由Apache创建的日志模块。
         * Commons Logging的特色是，它可以挂接不同的日志系统，并通过配置文件指定挂接的日志系统。
         * 默认情况下，Commons Loggin自动搜索并使用Log4j（Log4j是另一个流行的日志系统），如果没有找到Log4j，再使用JDK Logging。
         * 使用Commons Logging只需要和两个类打交道，并且只有两步：
         * 第一步，通过LogFactory获取Log类的实例； 第二步，使用Log实例的方法打日志。
         * 
         * Commons Logging定义了6个日志级别：
         * FATAL
         * ERROR
         * WARNING
         * INFO         默认级别是INFO。
         * DEBUG
         * TRACE
         * 
         * 小结
         * Commons Logging是使用最广泛的日志模块；
         * Commons Logging的API非常简单；
         * Commons Logging可以自动检测并使用其他日志模块。
         */

        Log log = LogFactory.getLog(FnCommonsLogging.class);
        log.info("start...");
        log.warn("end.");
        
        foo();
        
        Personlog xiaoming = new Personlog();
        xiaoming.foo();
        
        Studentlog xiaohong = new Studentlog();
        xiaohong.bar();
        
        // 此外，除了标准的info(String)外，还提供了一个非常有用的重载方法：info(String, Throwable)，这使得记录异常更加简单。
        try {
            process1();
        } catch (Exception e) {
            log.error("got exception!", e);
        } 
        
    }
    // 使用Commons Logging时，如果在静态方法中引用Log，通常直接定义一个静态类型变量
    static final Log log = LogFactory.getLog(FnCommonsLogging.class);
    static void foo() {
        log.info("静态方法foo");
    }
    
    // 由于Java类的动态特性，子类获取的log字段实际上相当于LogFactory.getLog(Student.class)，但却是从父类继承而来，并且无需改动代码。
    private static void process1() throws IOException {
        System.out.println("process1 run");
        process2();
    }
    private static void process2() {
        // TODO Auto-generated method stub
        Integer.parseInt(null); // 会抛出NumberFormatException
    }
}
// 在实例方法中引用Log，通常定义一个实例变量
// 实例变量log的获取方式是LogFactory.getLog(getClass())
// 这种方式有个非常大的好处，就是子类可以直接使用该log实例。
class Personlog {
    protected final Log log = LogFactory.getLog(getClass());

    void foo() {
        log.info("实例foo");
    }
}
// 在子类中使用父类实例化的log:
class Studentlog extends Personlog {
    void bar() {
        log.info("子类bar");
    }
}

